package com.ysh.smartplatform.service.impl;

import com.ysh.smartplatform.cache.CategoryCache;
import com.ysh.smartplatform.constans.ResultCode;
import com.ysh.smartplatform.event.CategoryChangeEvent;
import com.ysh.smartplatform.exceptions.AddDataException;
import com.ysh.smartplatform.exceptions.FindDataException;
import com.ysh.smartplatform.mapper.CategoryMapper;
import com.ysh.smartplatform.pojo.BaseUser;
import com.ysh.smartplatform.pojo.SysCategory;
import com.ysh.smartplatform.pojo.SysUserInfo;
import com.ysh.smartplatform.service.CategoryService;
import com.ysh.smartplatform.utils.SecurityUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 袁胜虎 on 2022/9/6 21:35
 */
@Service
@Transactional
public class CategoryServiceImpl implements CategoryService {
    private ApplicationContext applicationContext;


    @Autowired
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    private CategoryCache categoryCache;

    @Autowired
    public void setCategoryCache(CategoryCache categoryCache) {
        this.categoryCache = categoryCache;
    }

    private CategoryMapper categoryMapper;

    @Autowired
    public void setCategoryMapper(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
    }

    @Override
    public void addCategory(SysCategory category) {
        //校验数据,数据现在通过我们的注解来校验
        //设置相关数据
        //设置创建者为当前登录用户,我们的登录用户的数据在session中保存着,我们可以从session中获取
        BaseUser userInfo = SecurityUtils.getLoginUser();
        category.setCreateBy(userInfo.getUsername());
        //添加之前先查询数据是否存在
        SysCategory sysCategory = categoryMapper.findByCategoryName(category.getCategoryName());
        //判断查询出来的分类是不是被删除了,如果是删除了就增加新的数据,如果没有删除就抛出异常
        //老的数据重命名,新的数据用正常的名字,原因是后面新的用的多,老的分类到最后没有使用的情况下就可以真的不使用了
       if (sysCategory != null && sysCategory.getStatus() == 1){
           //正常存在,抛出异常
           throw  new AddDataException("分类已经存在",ResultCode.DATA_ALREADY_EXIST);
       }else if (sysCategory != null && sysCategory.getStatus() == 0){
           //存在但是被删除了
           //将老的分类的名字换掉,但是为了避免使用老设备的用户产生异或,我们可以更新带有特殊字符的名字,返回的时候将特殊字符去掉
           sysCategory.setCategoryName(sysCategory.getCategoryName()+"teshuzifu");
           //更新数据
           sysCategory.setCreateBy(userInfo.getUsername());
           categoryMapper.updateCategory(sysCategory);
       }
        //添加数据
        categoryMapper.addCategory(category);
        //更新缓存,写什么?发布事件,交给缓存自己更新
        applicationContext.publishEvent(new CategoryChangeEvent());

    }

    @Override
    public List<SysCategory> findAllCategories() {
        //查询缓存,但是注意我们查询所有数据的时候应该是返回有效的缓存
        List<SysCategory> categoryList = categoryCache.getCategoryList();
        //返回有效的数据
        return categoryList.stream().filter(category -> category.getStatus() == 1).collect(Collectors.toList());
    }

    @Override
    public SysCategory findById(Long cId) {
//        //我们分类数据在缓存中保存着,所以这里可以从缓存中查询
//        //我们缓存里面是一个集合,怎么根据一个id从集合中找到数据?
//        //        List<SysCategory> categoryList = categoryCache.getCategoryList();
////        for (SysCategory sysCategory : categoryList) {
////            if (sysCategory.getCId().equals(cId)) {
////                return sysCategory;
//            }
//        }
        //上面的方式每次都要遍历几乎所有的分类,特别麻烦,浪费时间,我们既然已经有所有的缓存了,能不能用map额外保存一份,然后每次用id作为key从map中直接查询
        SysCategory sysCategory = categoryCache.get(cId);
        Assert.notNull(sysCategory,()->{
            throw  new FindDataException("分类不存在",ResultCode.DATA_NOT_EXIST);
        });
        return sysCategory;
    }

    @Override
    public void deleteById(Long cId) {
        if (cId == null){
            throw  new AddDataException("参数不存在",ResultCode.PARAM_CONTENT_EMPTY);
        }
        categoryMapper.deleteById(cId);

        applicationContext.publishEvent(new CategoryChangeEvent());
    }
}
